var arrangeOperationTask = function($startDate, $endDate, orderNums, controlNums, hostUrl, ajaxCallBack) {
	/**
	 * 当前页
	 */
	var $page = DWZ.context(), labelTemp,
	/**
	 * 作业单元上的任务
	 */
	workunitProcess = {},
	/**
	 * 添加进度到作业单元进度集
	 */
	addWorkUnitProcess = function(workUnitCode, barId) {
		if (!workUnitCode || !barId) {
			return;
		}
		if (!workunitProcess[workUnitCode]) {
			workunitProcess[workUnitCode] = {};
		}
		workunitProcess[workUnitCode][barId] = true;
	},
	/**
	 * 从作业单元进度集删除进度
	 */
	removeWorkUnitProcess = function(workUnitCode, barId) {
		if (!workUnitCode || !barId) {
			return;
		}
		if (!workunitProcess[workUnitCode]) {
			workunitProcess[workUnitCode] = {};
			return;
		}
		if (!delete workunitProcess[workUnitCode][barId]) {
			workunitProcess[workUnitCode][barId] = false;
		}
		var index = 0;
		$.each(workunitProcess[workUnitCode], function(key, value) {
			index++;
		})
		if (index === 0) {
			//console.log(workUnitCode, 'celear')
		}
	},
	/**
	 * 重置作业单元进度集
	 */
	resetWorkUnitProcess = function() {
		workunitProcess = {};
		var process = {};
		gantt.getGraphPanel().find('.jgantt-bar').each(function() {
			process = gantt.getProcessData(this.id);
			if (!workunitProcess[process.workUnitCode]) {
				workunitProcess[process.workUnitCode] = {};
			}
			workunitProcess[process.workUnitCode][this.id] = true;
		});
	},
	/**
	 * 行数据
	 */
	data = [],
	/**
	 * 按照优先级排序后的行数据
	 */
	priorityData,
	/**
	 * 工作中心——工艺工序 可用作业单元
	 */
	workUnitMap = {},
	/**
	 * 工作中心日历
	 */
	workCenterCalendarDaysMap = {},
	/**
	 * 作业单元日历
	 */
	workUnitCalendarDaysMap = {},
	/**
	 * 日历详情
	 */
	workDayPeriodsMap = {},
	/**
	 * 完整工作日时长
	 */
	workDayPeriods = {},
	/**
	 * 工艺工序【作业单元】产能
	 */
	capacitiesMap = {},
	/**
	 * 优先级
	 */
	priority = 0,
	/**
	 * 甘特图面板（jQuery）
	 */
	$jgantt = $('#jGantt', $page),
	/**
	 * 甘特图数据
	 */
	gantt = {},
	/**
	 * 获取行id
	 */
	getRowId = function(rowIndex) {
		return 'jGantt-datarow-' + rowIndex;
	},
	/**
	 * 获取进度id
	 */
	getBarId = function(rowIndex) {
		return 'jGantt-processbar-' + rowIndex;
	},
	/**
	 * 进度id转行id
	 */
	barId2RowId = function(barId) {
		return barId.replace('-processbar-', '-datarow-');
	},
	/**
	 * 行id转进度id
	 */
	rowId2BarId = function(rowId) {
		return rowId.replace('-datarow-', '-processbar-');
	},
	/**
	 * 作业单元背景色
	 */
	bgpIndex = 0, workUnitBg = {}, getBgPosition = function(workUnitCode) {
		if (workUnitBg[workUnitCode]) {
			return workUnitBg[workUnitCode];
		}
		// 目前77个颜色，使用完后循环
		var pTop = -26 * (bgpIndex % 77);
		bgpIndex++;
		workUnitBg[workUnitCode] = {
			backgroundPosition: '0px ' + pTop + 'px'
		};
		return workUnitBg[workUnitCode];
	},
	/**
	 * 检查超期
	 */
	validateOvertime = function(barId, processData) {
		var $row = gantt.getRow(barId2RowId(barId)), days = Math.floor((processData.end.getStandardDate() - new Date(processData._parent.requirementDate).getStandardDate()) / 86400000);
		if (days > 0) {
			$('.warning-icon', $row).attr('title', '工序任务计划已经延期' + days + '天！').show();
		} else {
			$('.warning-icon', $row).removeAttr('title').hide();
		}
	},
	/**
	 * 获取进度提示信息
	 */
	getBarLabel = function(barId, processData) {
		var $row = gantt.getRow(barId2RowId(barId)), data = $.extend({}, processData);
		$.extend(data, {
			workUnitText: $row.find('select[name=workUnitCode]').find('option:selected').text()
		});
		processData.workUnitText = data.workUnitText;
		data.plannedStartDateTime = data.start.formatDate('yyyy-MM-dd HH:mm');
		data.plannedEndDateTime = data.end.formatDate('yyyy-MM-dd HH:mm');
		data.plannedHours = secondsToHours(processData.produceTime) || 0.01;
		data.actualHours = data.actualHours || 0;
		data.operationTaskNum = data.operationTaskNum || '';
		
		if (data.plannedHours > 0) {
			data.progress = ((data.actualHours || 0) / data.plannedHours * 100).toFixed(2) + '%';
		}
		$row.find('[field=plannedHours]').text(data.plannedHours ? data.plannedHours + 'h' : '');
		$row.find('[field=progress]').text(data.progress || '');
		$row.find('[field=plannedQuantity]').text(data.plannedQuantity);

		var label = new String(labelTemp);
		$.each(data, function(key, value) {
			if (key == '_parent') {
				$.each(value, function(key, value) {
					label = label.replace('{' + key + '}', value || '');
				});
			} else {
				label = label.replace('{' + key + '}', value || '');
			}
		});
		return label;
	},
	/**
	 * 时间改变回调
	 */
	dateTimeChange = function() {
		var $this = $(this), $cell = $this.parent(), $row = $cell.parent(), rowIndex = $row.attr('rowIndex'), dateStr = this.value, data = gantt.getProcessData(rowIndex);
		if (!dateStr) {
			$jgantt.jGantt('removeProcessBar', getBarId(rowIndex));
			delete data[$cell.attr('field')];
			return false;
		}
		if ($this.is('.setValueModel')) {
			return false;
		}
		data[$cell.attr('field')] = dateStr.parseDate('yyyy-MM-dd HH:mm:ss');
		if (data.start && data.end) {
			data.workUnitCode = $row.find('select[name=workUnitCode]').val();
			data.css = getBgPosition(data.workUnitCode);
			$jgantt.jGantt('updateProcessBar', getBarId(rowIndex), data);
		}
	},
	/**
	 * 进度条改变回调，设置开始结束时间
	 */
	setDateTime = function(barId, process) {
		// 得到进度条对应的行及单元格
		var $row = gantt.getRow(barId2RowId(barId)), $startCell = $row.find('.dataCell[field=start]'), $endCell = $row.find('.dataCell[field=end]');
		if (!$row.is('.rootRow')) {
			// 分别设置开始结束时间
			$('>.date', $startCell).addClass('setValueModel').detach().val(process.start.format()).prependTo($startCell);
			$('>.date', $endCell).addClass('setValueModel').detach().val(process.end.format()).prependTo($endCell);
		} else {
			$startCell.text(process.start.format());
			$endCell.text(process.end.format());
		}
		return $row;
	},
	/**
	 * 追加开始、结束时间单元格
	 */
	appendDateCell = function($row, $cell, css, value) {
		$cell.empty();
		var $dateInput = $('<input datefmt="yyyy-MM-dd HH:mm:ss" readonly="readonly" class="textInput date" type="text"/>');
		if (!$row.is('.rootRow')) {
			$cell.append($dateInput).append($('<a class="inputDateButton" href="javascript:;"/>').focus(function() {
				$dateInput.removeClass('setValueModel');
			}));
			$dateInput.attr({
				minDate: $startDate,
				maxDate: $endDate,
				dateGroup: $row.attr('id'),
				disabled: !$row.find('.dataCell[field=workUnitCode]').find('option').length,
				value: value || ''
			}).addClass(css);
		} else {
			$cell.addClass('dateInputCell').text(value || '');
		}
	},
	/**
	 * 获取日历时长（秒） return {Number}
	 */
	getPeriodicSeconds = function(dayTypeCode, startTimeObj, endTimeObj) {
		// 如果是获取整天的工作时长，且已经有缓存，直接使用缓存
		if (!startTimeObj && !endTimeObj && workDayPeriods[dayTypeCode]) {
			return workDayPeriods[dayTypeCode];
		}
		// 相关变量
		var seconds = 0, startSeconds = 0, endSeconds = 0, startTimeSeconds = 0, endTimeSeconds = 0;
		// 参数有开始时间时，需要转换
		if (startTimeObj && startTimeObj.time) {
			startTimeSeconds = parseTimeToNumber(startTimeObj.time, startTimeObj.day);
		}
		if (endTimeObj && endTimeObj.time) {
			endTimeSeconds = parseTimeToNumber(endTimeObj.time, endTimeObj.day);
		}
		// 遍历日历时段
		$.each(workDayPeriodsMap[dayTypeCode] || [], function() {
			if (this.startTime && this.endTime) {
				// 分别转换日历时段的开始时间和结束时间
				var startSeconds = parseTimeToNumber(this.startTime, this.nextDayFlag);
				var endSeconds = parseTimeToNumber(this.endTime, this.nextDayFlag || this.spanDaysFlag);
				// 如果参数里的开始时间大于日历时段的结束时间，遍历下一条
				if (startTimeSeconds > endSeconds) {
					return true;
				}
				// 如果参数里的结束时间小于日历时段的开始时间，停止遍历
				if (endTimeSeconds > 0 && endTimeSeconds < startSeconds) {
					return false;
				}
				// 如果参数里的开始时间大于日历时段的开始时间，以参数开始
				if (startTimeSeconds > startSeconds) {
					startSeconds = startTimeSeconds;
				}
				// 如果参数里的结束时间小于日历结束时间，以参数结束
				if (endTimeSeconds >= startSeconds && endTimeSeconds <= endSeconds) {
					seconds += (endTimeSeconds - startSeconds);
					return false;
				}
				// 累加结束时间减开始时间
				seconds += (endSeconds - startSeconds);
			}
		});
		// 参数不带开始时间和结束时间，则结果为整个日历的有效工作时间
		if (!startTimeObj && !endTimeObj) {
			workDayPeriods[dayTypeCode] = seconds;
		}
		return seconds;
	},
	/**
	 * 获取指定日历类型的开始时间 return { time: 'HH:mm:ss', day: 0 || 1 }
	 */
	getStartTime = function(dayTypeCode) {
		return transformSecondsToTime(parseTimeToNumber(workDayPeriodsMap[dayTypeCode][0].startTime));
	},
	/**
	 * 根据开始时间、耗时及日历信息获取当日结束时间 return { time: 'HH:mm:ss', day: 0 || 1 }
	 */
	getEndTime = function(dayTypeCode, seconds, startTimeObj) {
		var startSeconds = 0, endSeconds = 0, endTimeObj, startTimeSeconds = 0;
		// 有日历时
		if (dayTypeCode) {
			// 参数有开始时间时，需要转换
			if (startTimeObj && startTimeObj.time) {
				startTimeSeconds = parseTimeToNumber(startTimeObj.time, startTimeObj.day);
			}
			// 遍历日历时段
			$.each(workDayPeriodsMap[dayTypeCode], function() {
				if (this.startTime && this.endTime) {
					// 分别转换日历时段的开始时间和结束时间
					startSeconds = parseTimeToNumber(this.startTime, this.nextDayFlag);
					endSeconds = parseTimeToNumber(this.endTime, this.nextDayFlag || this.spanDaysFlag);
					// 如果参数里的开始时间大于日历时段的结束时间
					if (startTimeSeconds > endSeconds) {
						return true;
					}
					// 如果参数里的开始时间大于日历时段的开始时间
					if (startTimeSeconds > startSeconds) {
						startSeconds = startTimeSeconds;
					}
					// 日历时段结束时间大于开始时间加需要时长时，遍历结束
					if (startSeconds + seconds < endSeconds) {
						// 将时长转换为对应的时间
						endTimeObj = transformSecondsToTime(startSeconds + seconds);
						return false;
					} else {
						// 需要的时长累减
						seconds = seconds - (endSeconds - startSeconds);
					}
				}
			});
			// 如果遍历完时间仍然不够，则以当前日历的最后一个时段的结束时间为准
			if (!endTimeObj) {
				endTimeObj = transformSecondsToTime(endSeconds);
			}
			return endTimeObj;
		} else {
			// 没有日历时，直接开始时间加时长，计算出结束时间
			startTimeSeconds = parseTimeToNumber(startTimeObj.time, startTimeObj.day);
			return transformSecondsToTime(startTimeSeconds + seconds);
		}
		return undefined;
	},
	/**
	 * 时间字符串转【HH:mm:ss】换为当天的秒数
	 */
	parseTimeToNumber = function(timeStr, day) {
		var timeArr = timeStr.trim().split(':');
		return (day || 0) * 24 * 60 * 60 + parseInt(timeArr[0] || 0) * 60 * 60 + parseInt(timeArr[1] || 0) * 60 + parseInt(timeArr[2] || 0);
	},
	/**
	 * 秒数转换为时间对象 return { time: 'HH:mm:ss', day: 0 || 1 }
	 */
	transformSecondsToTime = function(seconds) {
		// 分别计算时分秒
		var hours = Math.floor(seconds / (60 * 60)), minutes = Math.floor((seconds % (60 * 60)) / 60), seconds = (seconds % (60 * 60)) % 60;
		return {
			day: Math.floor(hours / 24), // 跨天数
			time: patchTime(hours % 24) + ':' + patchTime(minutes) + ':' + patchTime(seconds)
		};
	},
	/**
	 * 10以下数字前补0 return {String}
	 */
	patchTime = function(t) {
		if (t < 10) {
			t = '0' + t;
		}
		return t;
	},
	/**
	 * 把日期和秒转换的时间转换成日期 return {Date}
	 */
	buildDateTime = function(dateStr, timeObj) {
		var date = dateStr.parseDate('yyyy-MM-dd'), time = '00:00:00';
		if (timeObj) {
			date.setDate(date.getDate() + timeObj.day);
			time = timeObj.time;
		}
		return (date.formatDate('yyyy-MM-dd') + ' ' + time).parseDate('yyyy-MM-dd HH:mm:ss');
	},
	/**
	 * 产能 return 数量/秒
	 */
	getCapacity = function(processOperationId, workUnitCode) {
		var capacity;
		$.each(capacitiesMap[processOperationId] || [], function() {
			// 当没有工艺工序作业单元产能时，以工艺工序产能计算
			if (!capacity && this.workUnitCode === 'null') {
				capacity = this;
			}
			// 找到工艺工序作业单元产能，遍历结束
			if (this.workUnitCode == workUnitCode) {
				capacity = this;
				return false;
			}
		});
		// 没有产能数据、小时或产能不合法，均视为无产能数据
		if (!capacity || capacity.standardHours <= 0 || capacity.standardCapacity <= 0) {
			return undefined;
		}
		return capacity.standardCapacity / capacity.standardHours / 3600;
	},
	/**
	 * 获取作业单元或工作中心的日历列表
	 */
	getCalendarDays = function(unitCode, centerCode) {
		return workUnitCalendarDaysMap[unitCode] || workCenterCalendarDaysMap[centerCode] || [];
	},
	/**
	 * 获取指定时间的日历开始时间 return {startDate: 'yyyy-MM-dd', day: 0 || 1, time: 'HH:mm:ss'}
	 */
	getCalendarDay = function(calendarDays, date) {
		var obj = {};
		$.each(calendarDays || [], function() {
			// 时间日期对应日历或之后的第一个日历
			if (this.calendarDate == date.formatDate('yyyy-MM-dd')) {
				var workDayPeriods = workDayPeriodsMap[this.dayTypeCode];
				if (workDayPeriods && workDayPeriods.length) {
					var t = workDayPeriods[0];
					// 如果时间比当前日历的第一个时间段小则设置当前日期的日历日期为前一天，并且跨天
					if (buildDateTime(this.calendarDate, {
						day: t.nextDayFlag || 0,
						time: t.startTime
					}) > date) {
						var startDate = new Date(date);
						startDate.setDate(date.getDate() - 1);
						obj.startDate = startDate.formatDate('yyyy-MM-dd');
						obj.day = 1;
					}
				}
				return false;
			} else if (this.calendarDate > date.formatDate('yyyy-MM-dd')) {
				return false;
			}
		});
		// 否则设置日历日期为当前日期
		if (!obj.startDate) {
			obj.startDate = date.formatDate('yyyy-MM-dd');
			obj.day = 0
		}
		obj.time = date.formatDate('HH:mm:ss');
		return obj;
	},
	/**
	 * 根据开始时间、结束时间获取以及工作中心作业单元数据，获取时间段内的有效工时
	 */
	getIntervalTime = function(startTime, endTime, workCenterCode, workUnitCode) {
		var seconds = 0, calendarDays = getCalendarDays(workUnitCode, workCenterCode), startTimeObj = getCalendarDay(calendarDays, startTime), startDate = startTimeObj.startDate, endTimeObj = getCalendarDay(calendarDays, endTime), endDate = endTimeObj.startDate;
		$.each(calendarDays || [], function() {
			if (this.calendarDate >= startDate && this.calendarDate <= endDate) {
				// 如果起止时间同一天
				if (this.calendarDate == startDate && this.calendarDate == endDate) {
					seconds += getPeriodicSeconds(this.dayTypeCode, startTimeObj, endTimeObj);
					return false;
				}
				// 起始日期计算开始时间到日历结束时间有效时长
				if (this.calendarDate == startDate) {
					seconds += getPeriodicSeconds(this.dayTypeCode, startTimeObj);
				} else if (this.calendarDate >= endDate) {
					// 截止日期计算日历开始到结束时间有效时长
					if (this.calendarDate == endDate) {
						seconds += getPeriodicSeconds(this.dayTypeCode, undefined, endTimeObj);
					}
					return false;
				} else {
					// 其他情况视为满工作日时长
					seconds += getPeriodicSeconds(this.dayTypeCode);
				}
			} else if (this.calendarDate > endDate) {
				return false;
			}
		});
		return seconds;
	},
	/**
	 * 获取生产时长
	 */
	getProduceTime = function(quantity, processOperationId, workUnitCode) {
		if (!workUnitCode) {
			return undefined;
		}
		var capacity = getCapacity(processOperationId, workUnitCode);
		// 没有产能数据不能排产
		if (!capacity) {
			return undefined;
		}
		return quantity / capacity;
	},
	/**
	 * 获取排产时间
	 */
	getProcessDateTime = function(calendarDays, startTime, endTime, produceTime) {
		var startTimeObj = getCalendarDay(calendarDays, startTime), startDate = startTimeObj.startDate, endTimeObj;
		if (endTime) {
			endTimeObj = getCalendarDay(calendarDays, endTime), endDate = endTimeObj.startDate;
		}

		var obj = {
			startDate: startDate
		}, seconds = 0;

		$.each(calendarDays || [], function() {
			// 开始日期之前的日历跳过
			if (this.calendarDate < startDate) {
				return true;
			}
			if (endTimeObj && endTimeObj.startDate > this.calendarDate) {
				return false;
			}
			// 当前日期有效工作时长
			var length = 0;
			// 如果开始日期有日历
			if (this.calendarDate == startDate) {
				// 没有指定的开始时间
				if (!startTimeObj) {
					startTimeObj = getStartTime(this.dayTypeCode);
				}
				length = getPeriodicSeconds(this.dayTypeCode, startTimeObj);
			} else {
				length = getPeriodicSeconds(this.dayTypeCode);
			}
			// 累计有效市场加当前日期有效时长满足生产需要的有效时长时，遍历结束，计算出结束日期
			if (seconds + length >= produceTime) {
				obj.endDate = this.calendarDate;
				// 结束日期不是开始日期时，开始时间以当前日期日历开始时间为准
				if (this.calendarDate != startDate) {
					obj.endTimeObj = getEndTime(this.dayTypeCode, produceTime - seconds);
				} else {
					obj.endTimeObj = getEndTime(this.dayTypeCode, produceTime - seconds, startTimeObj);
				}
				// 结束遍历
				return false;
			} else {
				// 不满足时累加
				seconds += length;
			}
		});
		obj.startTimeObj = startTimeObj || {
			day: 0,
			time: '00:00:00'
		};
		return obj;
	},
	/**
	 * 获取进度数据
	 */
	getProcessData = function(startDate, startTimeObj, quantity, workCenterCode, processOperationId, workUnitCode, rowIndex) {
		var $waring = $('.warning-icon', gantt.getRow(getRowId(rowIndex))).removeAttr('title').hide();
		if (!workUnitCode) {
			$waring.attr('title', '没有可用的作业单元，不能自动排产').show();
			return undefined;
		}
		var capacity = getCapacity(processOperationId, workUnitCode), startObj;
		// 没有产能数据不能排产
		if (!capacity) {
			$waring.attr('title', '没有产能数据，不能自动排产').show();
			return undefined;
		}

		var calendarDays = getCalendarDays(workUnitCode, workCenterCode);
		// 没有工作日历不能排产
		if (!calendarDays) {
			$waring.attr('title', '没有日历数据，不能自动排产').show();
			return undefined;
		}

		if (startTimeObj) {
			startObj = $.extend({}, startTimeObj, true);
		}
		// 根据产能和计划数量获取生产需要的有效时间
		var time = quantity / capacity, seconds = 0, obj = {};
		// 遍历范围内的日历，得到开始结束时间
		$.each(calendarDays, function() {
			// 开始日期之前的日历跳过
			if (this.calendarDate < startDate) {
				return true;
			}
			// 当前日期有效工作时长
			var length = 0;
			if (this.calendarDate == startDate) {
				length = getPeriodicSeconds(this.dayTypeCode, startTimeObj);
			} else {
				length = getPeriodicSeconds(this.dayTypeCode);
			}
			// 累计有效市场加当前日期有效时长满足生产需要的有效时长时，遍历结束，计算出结束日期
			if (seconds + length >= time) {
				// 结束日期不是开始日期时，开始时间以当前日期日历开始时间为准
				if (!startTimeObj || this.calendarDate !== startDate) {
					startTimeObj = getStartTime(this.dayTypeCode);
					if (!startObj) {
						startObj = $.extend({}, startTimeObj, true);
					}
				}
				// 计算当前日期结束时间
				var endTimeObj = getEndTime(this.dayTypeCode, time - seconds, startTimeObj);
				obj.startDate = this.calendarDate;
				obj.startTimeObj = endTimeObj;
				$.extend(obj, {
					start: buildDateTime(startDate, startObj),
					end: buildDateTime(this.calendarDate, endTimeObj)
				}, true);
				// 结束遍历
				return false;
			} else {
				// 不满足时累加
				seconds += length;
			}
		});
		obj.plannedQuantity = quantity;
		obj.css = getBgPosition(workUnitCode);
		obj.produceTime = time;
		if (!obj.end || !obj.start) {
			$waring.attr('title', '该工序不能在有效的时间内排产完成！').show();
			return undefined;
		}
		return obj;
	},
	/**
	 * 作业单元优选
	 * 
	 * @param startDateTime 排产最小开始时间
	 * @param workCenterCode 工作中心
	 * @param workUnitCodes 可选作业单元
	 * @param quantity 数量
	 * @param processOperationId 工艺工序id
	 */
	seekOptimumUnit = function(startDateTime, workCenterCode, workUnitCodes, quantity, processOperationId, rowIndex) {
		var _length = 0, workUnitArrangement = {}, produceTimeObj = {}, returnObj = {};
		// 遍历可选的作业单元，分别计算需要生产的时长
		$.each(workUnitCodes, function() {
			var workUnitCode = this, produceTime = getProduceTime(quantity, processOperationId, workUnitCode);
			// 如果没有产能则找下一个作业单元
			if (produceTime === undefined) {
				return true;
			}
			_length += 1;
			workUnitArrangement[workUnitCode] = [];
			produceTimeObj[workUnitCode] = produceTime;
			// 遍历作业单元已经排产的进度，放入数组
			$.each(workunitProcess[workUnitCode] || {}, function(key, flag) {
				var data = gantt.getProcessData(key);
				if (flag && data) {
					workUnitArrangement[workUnitCode].push({
						start: data.start,
						end: data.end
					});
				}
			});
			// 对时间进度排序，按照结束时间先后排序
			workUnitArrangement[workUnitCode].sort(function(a, b) {
				if (a.end > b.end) {
					return 1;
				}
				return -1;
			});
		});
		if (_length === 0) {
			$('.warning-icon', gantt.getRow(getRowId(rowIndex))).attr('title', '没有产能数据，不能自动排产').show();
		}
		var workUnitCode, selected = false, minStart, workunitSeeker = {};
		// 遍历排序后的作业单元已排进度
		$.each(workUnitArrangement, function(code, arrangements) {
			var calendarDays = getCalendarDays(code, workCenterCode);
			// 工时智能分析
			var start, prevProcess, intervalTime = 0;
			$.each(arrangements, function() {
				// 当前进度的开始时间大于最小开始时间，才有必要判断
				if (this.start > startDateTime) {
					// 有上一进度，且结束时间大于最小开始时间
					if (prevProcess && prevProcess.end > startDateTime) {
						intervalTime = getIntervalTime(prevProcess.end, this.start, workCenterCode, code);
						if (intervalTime >= produceTimeObj[code]) {
							start = prevProcess.end;
							return false;
						}
					} else {
						intervalTime = getIntervalTime(startDateTime, this.start, workCenterCode, code);
						if (intervalTime >= produceTimeObj[code]) {
							start = startDateTime;
							return false;
						}
					}
				}
				start = this.end;
				// 缓存上一个进度，用于跟下一个进度比较
				prevProcess = this;
			});
			// 如果没有开始时间或者开始时间小于上个进度的结束时间
			if (!start || start < startDateTime) {
				start = startDateTime;
			};
			workunitSeeker[code] = $.extend({}, getCalendarDay(getCalendarDays(code, workCenterCode), start));
		});
		var minEnd, bestProcess;
		// 针对可以生产的作业单元，分别计算结束时间，优先选择能够最早结束的作业单元
		$.each(workunitSeeker, function(code, obj) {
			var process = getProcessData(obj.startDate, {
				day: obj.day,
				time: obj.time
			}, quantity, workCenterCode, processOperationId, code, rowIndex);
			if (process && process.end && (!minEnd || minEnd > process.end)) {
				minEnd = process.end;
				bestProcess = $.extend(process, {
					workUnitCode: code,
					css: getBgPosition(code)
				});
			}
		});
		return bestProcess;
	},
	/**
	 * 获得所选生产管理号
	 */
	getSelectedRowIndexs = function() {
		var rowIndexs = [];
		$('>.rootRow:not([readonly])>.dataCell[field=productionControlNum]>[type=checkbox]', gantt.$left_content).each(function() {
			if (this.checked) {
				rowIndexs.push(parseInt($(this).closest('.dataRow').attr('rowIndex')));
			}
		});
		return rowIndexs;
	},
	/**
	 * 优先级排序
	 */
	prioritySort = function() {
		// 复制原始数据
		priorityData = $.extend([], data, true);
		// 按照优先级排序,排序规则如下
		priorityData.sort(function(a, b) {
			// 只读的放后面
			if (b.readonly) {
				return -1;
			}
			// 1、都有优先级，优先级越小越靠前；
			if (a._priority_ && b._priority_ && a._priority_ > b._priority_) {
				return 1;
			}
			// 2、有优先级的比没有优先级的靠前；
			else if (!a._priority_ && b._priority_) {
				return 1;
			}
			// 3、都没有优先级的，按照行的顺序排
			else if (!a._priority_ && !b._priority_ && a._rowIndex > b._rowIndex) {
				return 1;
			}
			return -1;
		});
	},
	/**
	 * 秒数转为时长
	 */
	secondsToHours = function(seconds) {
		if (!isNaN(seconds)) {
			var hours = seconds / 60 / 60;
			if (parseInt(hours) == hours || hours.toFixed(1) == hours || hours.toFixed(2) == hours) {
				return hours;
			}
			hours = hours.toFixed(2);
			if (hours == '0.00') {
				hours = 0.01;
			}
			return hours;
		}
		return 0;
	};

	/**
	 * 生成甘特图
	 */
	$jgantt.jGantt({
		start: $startDate.parseDate('yyyy-MM-dd'),
		end: $endDate.parseDate('yyyy-MM-dd'),
		scale: 1,
		model: 'mwd',
		childrenField: 'processOperations',
		updateNextBar: false,
		scrollLoad: false,
		scrollLoaded: function(start, end) {
//			console.log(start, end);
		},
		processCreated: function(barId, process) {
			if (!barId || !process) {
				return;
			}
			var $row = setDateTime(barId, process);
			addWorkUnitProcess(process.workUnitCode, barId);
		},
		processUpdated: function(barId, process, flag) {
			if (!barId || !process) {
				return;
			}
			var $row = setDateTime(barId, process);
			addWorkUnitProcess(process.workUnitCode, barId);
			if ($row.is('.rootRow') || !$('#updateNextBar', $page)[0].checked || flag == false) {
				return;
			}
			if (process._parent) {
				var tasks = process._parent.processOperations, len = tasks.length;
				for (var index = 0; index < len; index++) {
					var task = tasks[index];
					if (task._rowIndex > process._rowIndex) {
//						delete task.start
//						delete task.end
						removeWorkUnitProcess(task.workUnitCode, getBarId(task._rowIndex));
					}
				}
				
				var unitArrangements = [];
				
				$.each(workunitProcess[process.workUnitCode] || {}, function(key, flag) {
					if (key == barId) {
						return true;
					}
					var data = gantt.getProcessData(key);
					if (flag && data) {
						unitArrangements.push({
							start: data.start,
							end: data.end,
							rowIndex: data._rowIndex
						});
					}
				});
				// 对时间进度排序，按照结束时间先后排序
				unitArrangements.sort(function(a, b) {
					if (a.end > b.end) {
						return 1;
					}
					return -1;
				});
				var overlapping = false, $bar = gantt.getBar(barId);
				$.each(unitArrangements, function(key, obj) {
					if ((process.start <= obj.start && process.end >= obj.end)
					|| (process.start > obj.start && process.start < obj.end)
					|| (process.end > obj.start && process.end < obj.end)) {
						var $warning = $('<div class="bar-warning bar-warning-upper"><div class="arrow"></div></div>')
						.append('该任务单排产时间和第' + (obj.rowIndex + 1) + '行时间有冲突').append('<br/>')
						.append('&nbsp;' + obj.start.formatDate('yyyy-MM-dd HH:mm') + ' - ' + obj.end.formatDate('yyyy-MM-dd HH:mm'));
						$bar.css({
							zIndex: 2000
						}).addClass('warning').append($warning.show());
						overlapping = true;
						if (parseInt($bar[0].style.top) - $jgantt.find('.jgantt-content').scrollTop() < 50) {
							$warning.removeClass('bar-warning-upper').addClass('bar-warning-under');
						}
						return false;
					}
				});
				
				if (!overlapping) {
					$bar.removeClass('warning');
					$bar.find('.bar-warning').remove();
				}
				
				arrangeControl.apply(process._parent, [true, process._rowIndex + 1]);
			}
		},
		processRemoved: function(barId, process) {
			if (!barId || !process) {
				return;
			}
			var $row = gantt.getRow(barId2RowId(barId));
			$row.find('[field=plannedHours]').empty();
			$row.find('.date').val('');
			removeWorkUnitProcess(process.workUnitCode, barId);
		},
		processChanged: function(operationType, barId, process) {
			if ((operationType == 'create' || operationType == 'update') && barId && process) {
				var $row = gantt.getRow(barId2RowId(barId));
				if ($row.is('.rootRow')) {
					return;
				}
				validateOvertime(barId, process);
				var $bar = gantt.getBar(barId), label = getBarLabel(barId, process);
				$bar.find('.bar-label').text(label);
			}
		},
		columns: [{
			field: 'warning',
			text: '警告',
			width: 30,
			dataRender: function($row, $cell) {
				$cell.append('<div class="warning-icon"/>');
			}
		}, {
			field: 'productionControlNum',
			text: '',
			type: '_checkbox',
			width: 27,
			dataRender: function($row, $cell, obj) {
				if (!$row.is('.rootRow')) {
					$cell.empty();
				}
				if (obj.readonly || (obj._parent && obj._parent.readonly)) {
					$row.attr('readonly', true);
					$cell.find(':checkbox').attr('disabled', true);
				}
			}
		}, {
			field: '_index',
			text: '序号',
			width: 30
		}, {
			field: 'productionControlNum',
			text: '生产管理号',
			width: 105,
			dataRender: function($row, $cell) {
				if (!$row.is('.rootRow')) {
					$cell.empty();
				}
			}
		}, {
			field: '_priority',
			text: '优先级',
			width: 45,
			dataRender: function($row, $cell, obj, column) {
				if (!$row.is('.rootRow')) {
					return;
				}
				obj._priority_ = obj._priority_ || ++priority;
				$cell.append($('<input class="priority integer" min="0" max="200" type="text"/>').focus(function() {
					$(this).addClass('focus');
				}).blur(function() {
					$(this).removeClass('focus');
				}).change(function() {
					obj._priority_ = parseInt(this.value);
				}).val(obj._priority_));
			}
		}, {
			field: 'plannedHours',
			text: '计划时长',
			width: 60,
			dataRender: function($row, $cell, obj, column) {
				
			}
		}, {
			field: 'operationText',
			text: '工序',
			width: 100
		}, {
			field: 'workUnitCode',
			text: '作业单元',
			width: 120,
			dataRender: function($row, $cell, obj, column) {
				$cell.empty();
				if ($row.is('.rootRow')) {
					return;
				}
				var $select = $('<select name="workUnitCode"/>').width(column.width - 5);
				obj.workCenterCode = obj._parent.workCenterCode, id = obj.id;
				var workUnitCodes = [];
				$.each(workUnitMap[obj.workCenterCode + '_' + id] || [], function(index, unit) {
					workUnitCodes.push(unit.workUnitCode);
					$('<option/>').attr({
						value: unit.workUnitCode,
						selected: unit.workUnitCode == obj.workUnitCode
					}).text(unit.workUnitText).appendTo($select);
				});
				if (workUnitCodes.length) {
					obj.workUnitCodes = workUnitCodes.join(',');
				}
				$select.change().attr('disabled', ((obj.statusECode || 1) > 1) || obj.disabled).appendTo($cell);
			}
		}, {
			field: 'materialText',
			text: '物料',
			width: 100
		}, {
			field: 'start',
			text: '开始时间',
			width: 146,
			dataRender: function($row, $cell, obj, column) {
				appendDateCell($row, $cell, 'from', obj.plannedStartDateTime ? new Date(obj.plannedStartDateTime).formatDate('yyyy-MM-dd HH:mm:ss') : '');
			}
		}, {
			field: 'end',
			text: '结束时间',
			width: 146,
			dataRender: function($row, $cell, obj, column) {
				appendDateCell($row, $cell, 'to', obj.plannedendDateTime ? new Date(obj.plannedendDateTime).formatDate('yyyy-MM-dd HH:mm:ss') : '');
			}
		}, {
			field: 'progress',
			text: '进度',
			width: 60
		}, {
			field: 'plannedQuantity',
			text: '数量',
			width: 60
		}, {
			field: 'productionOrderNum',
			text: '生产订单',
			width: 110,
			dataRender: function($row, $cell) {
				if (!$row.is('.rootRow')) {
					$cell.empty();
				}
			}
		}]
	}).css({
		marginLeft: -1,
		marginTop: -1
	});

	/**
	 * 甘特图数据
	 */
	gantt = $jgantt.jGantt('getGantt');

	/**
	 * 列表面板
	 */
	var gridPanel = $jgantt.jGantt('getGridPanel'),

	/**
	 * 视图面板
	 */
	graphPanel = $jgantt.jGantt('getGraphPanel').on('mouseenter', '.jgantt-bar.warning', function() {
		$(this).css({zIndex: 2000}).find('.bar-warning').show();
	}).on('mouseleave', '.jgantt-bar', function(){
		$(this).css({zIndex: 15}).find('.bar-warning').hide();
	}),

	/**
	 * 获取下一个进度数据
	 */
	getNextProcess = function(prevPOId, curPOId) {

	},
	/**
	 * 任务拆分
	 */
	separateTask = function(processData) {
		var process = $.extend({}, processData);
		process.operationTaskNum = '';
		process.workUnitCode = '';
		var $selectTem = gantt.getRow(getRowId(processData._rowIndex)).find('select[name=workUnitCode]').clone(), $cellTem = $('<div class="dataCell" />');
		var $rowTem = $('<div class="dataRow"/>').append($cellTem.clone().width(200).append($selectTem)).append($cellTem.clone().css({
			width: 107,
			border: 'none'
		}).append('<input type="text" class="textInput number" min="1"/>'));
		$.pdialog.open('', "separateOperationTask", "作业拆分", {
			height: 390,
			width: 630,
			max: false,
			mask: true,
			resizable: false,
			maxable: false,
			minable: false,
			callback: function($content) {
				$content.append($page.find('#separateOperationTask').clone().show());
				$content.find('#workunit').val(processData.workUnitText);
				$content.find('#quantity').val(processData.plannedQuantity);
				var $form = $content.find('#separateTaskForm');
				var $grid = $content.find('#taskGrid');
				$grid.jGrid({
					autoLoad: false,
					pageable: false,
					hasBorder: true,
					columnresizeable: false,
					orderable: false,
					wrapTD: false,
					trselectable: false,
					height: 200,
					width: 618,
					columns: [{
						field: '_index',
						text: '序号',
						width: 40
					}, {
						field: 'workUnitCode',
						text: '作业单元',
						width: 150,
						tdrender: function($td, obj) {
							var $select = $selectTem.clone();
							if (obj.workUnitCode === processData.workUnitCode) {
								$select.attr('disabled', true).find('option[value=' + processData.workUnitCode + ']').attr('selected', true);
							}
							$td.empty().append($select);
						}
					}, {
						field: 'plannedQuantity',
						text: '数量',
						width: 200,
						tdrender: function($td, obj) {
							$td.empty().append($('<div/>').append($('<input type="text" class="textInput number required plannedQuantity" min="1"/>').attr({
								min: 0,
								max: processData.plannedQuantity,
								name: 'plannedQuantity' + $grid.find('.gridTbody').find('tbody').children().length,
								autocomplete: 'off'
							}).val(obj.plannedQuantity || '')));
						}
					}, {
						field: '',
						text: getLocalRecource('opera.C', '操作'),
						width: 100,
						tdrender: function($td, obj) {
							if (obj.workUnitCode === processData.workUnitCode) {
								return false;
							}
							var text = getLocalRecource('delete.B');
							$td.empty().append($('<a title="' + text + '" class="btnDel" href="javascript:void(0)" />').click(function() {
								var $tbody = $td.closest('tbody');
								$td.closest('tr').remove();
								$tbody.find('td[columnField="_index"]').each(function(index, td) {
									$(this).text(index + 1);
								});
							}));
							return false;
						}
					}],
					gridbars: [{
						icon: 'add',
						text: getLocalRecource("add.B", '新增'),
						target: 'action',
						action: function() {
							$grid.jGrid('appendRow', {});
							return false;
						}
					}],
					fillData: [{
						workUnitCode: processData.workUnitCode,
						plannedQuantity: processData.plannedQuantity
					}]
				});
				$content.find('button.close').click(function() {
					$.pdialog.closeCurrent();
					return false;
				});
				$content.find('#separateTask').click(function() {
					if (!$form.valid()) {
						return false;
					}
					var units = [], quantitys = [], total = 0, isBreak = false;
					$grid.find('input.plannedQuantity').each(function(index, input) {
						var quantity = parseInt(this.value || 0);
						if (index === 0 && quantity <= 0) {
							alertMsg.error('原工序任务单数量不能小于1');
							isBreak = true;
							return false;
						}
						if (quantity > 0) {
							units.push($(input).closest('tr').find('select').val());
							quantitys.push(quantity);
							total += quantity;
						}
					});
					if (isBreak) {
						return false;
					}
					if (quantitys.length === 1) {
						alertMsg.error('工序任务单未做拆分！');
						return false;
					}
					if (total !== processData.plannedQuantity) {
						alertMsg.error('拆分后的总数量不等于拆分前的数量！');
						return false;
					}
					var rows = quantitys.length, rowData = [];
					for (var index = 1; index < rows; index++) {
						rowData.push($.extend({}, process, {
							workUnitCode: units[index],
							plannedQuantity: quantitys[index]
						}))
					}
					processData.plannedQuantity = quantitys[0];
					
					var $row = gantt.getRow(getRowId(processData._rowIndex));
					$row.find('div[field=plannedQuantity]').text(processData.plannedQuantity);
					gantt.insertRow(processData._rowIndex, rowData);
					if (!$('#displayAll', $page)[0].checked) {
						var $rows = $jgantt.find('.dataRow[readonly]').hide();
						$jgantt.find('.jgantt-right .content').height($jgantt.find('.dataRow:not([readonly])').length * 24);
					}
					$.pdialog.closeCurrent();
					resetWorkUnitProcess();
					// 重新计算拆分后的进度时间
					var operationTasks = processData._parent.processOperations, len = operationTasks.length;
					for (var index = 0; index < len; index++) {
						gantt.removeProcessBar(getBarId(operationTasks[index]._rowIndex));
					}
					arrangeControl.apply(processData._parent, [true]);
					return false;
				});
			}
		});
	}, resetTaskData = function() {

	},
	/**
	 * 合并工序任务单，删除不必要的属性，减少内存占用
	 */
	uniteOperationTasks = function(controls, operationTaskMap, readonly) {
		var data = [];
		$.each(controls || [], function(index, obj) {
			// 只要管理号的部分信息，减少前端缓存
			var control = {
				siteCode: obj.siteCode,
				productionOrderNum: obj.productionOrderNum,
				productionControlNum: obj.productionControlNum,
				materialCode: obj.materialCode,
				materialText: obj.materialText,
				plannedQuantity: obj.plannedQuantity,
				completedQuantity: obj.completedQuantity,
				uncompletedQuantity: obj.plannedQuantity - obj.completedQuantity,
				requirementDate: obj.requirementDate,
				workCenterCode: obj.workCenterCode,
				workCenterText: obj.workCenterText,
				readonly: readonly
			}, operations = [];

			$.each(obj.processOperations || [], function(index, op) {
				// 只要工艺工序部分信息
				var operation = {
					id: op.id,
					operationOrdinal: op.operationOrdinal,
					operationCode: op.operationCode,
					operationText: op.operationText
				}, tasks = (operationTaskMap[control.productionControlNum] || {})[operation.id];
				if (tasks) {
					$.each(tasks, function(index, t) {
						var task = {
							operationTaskNum: t.operationTaskNum,
							plannedHours: t.plannedHours,
							actualHours: t.actualHours,
							plannedQuantity: t.plannedQuantity,
							completedQuantity: t.completedQuantity,
							plannedStartDateTime: t.plannedStartDateTime,
							plannedendDateTime: t.plannedendDateTime,
							plannedWorkUnitCode: t.plannedWorkUnitCode,
							processOperationId: t.processOperationId,
							productionOrderNum: t.productionOrderNum,
							productionControlNum: t.productionControlNum,
							statusECode: t.statusECode,
							disabled: ((t.statusECode || 1) > 1) || readonly,
							workUnitCode: t.plannedWorkUnitCode,
							start: new Date(t.plannedStartDateTime),
							end: new Date(t.plannedendDateTime),
							css: getBgPosition(t.plannedWorkUnitCode),
							produceTime: (t.plannedHours || 0.01) * 60 * 60
						};
						operations.push($.extend({}, operation, task));
					});
				} else {
					operations.push(operation);
				}
			});
			control.processOperations = operations;
			data.push(control);
		});
		return data;
	}, 
	// 准备排产数据
	prepareArrangementData = function(json) {
		// 解析工作中心日历数据
		$.each(json.workCenterCalendarDaysMap, function(key, arr) {
			workCenterCalendarDaysMap[key] = [];
			$.each(arr, function() {
				var calendarDate = new Date(this.calendarDate).formatDate('yyyy-MM-dd'), dayTypeCode = this.dayTypeCode;
				workCenterCalendarDaysMap[key].push({
					calendarDate: calendarDate,
					dayTypeCode: dayTypeCode
				});
			});
		});
		// 解析作业单元日历数据
		$.each(json.workUnitCalendarDaysMap, function(key, arr) {
			workUnitCalendarDaysMap[key] = [];
			$.each(arr, function() {
				var calendarDate = new Date(this.calendarDate).formatDate('yyyy-MM-dd'), dayTypeCode = this.dayTypeCode;
				workUnitCalendarDaysMap[key].push({
					calendarDate: calendarDate,
					dayTypeCode: dayTypeCode
				});
			});
		});
		// 作业单元集
		$.extend(workUnitMap, json.workUnitMap, true);
		// 日历数据
		$.extend(workDayPeriodsMap, json.workDayPeriodsMap, true);
		// 产能数据
		$.extend(capacitiesMap, json.capacitiesMap, true);
	},
	// 作业单元相关历史数据
	getHistoryData = function(orderNums, controlNums) {
		DWZ.ajax({
			url: hostUrl + '/operationArrangement/getControlProcessOperations',
			data: {
				orderNums: orderNums.join(','),
				controlNums: controlNums.join(','),
				startDate: $startDate,
				endDate: $endDate
			},
			async: false,
			dataType: 'json',
			alert: false,
			success: function(json) {
				prepareArrangementData(json);
				var data = uniteOperationTasks(json.controls, json.operationTaskMap, true);
				if (data && data.length) {
					$.each(data, function() {
						gantt.createDataRow(this);
					});
				}
				// 更新所有的父进度条
				$.each(data, function(){
					// 筛选有确认点工序的管理号
					if (this.processOperations.length > 0) {
						gantt.updatePaternalBar(gantt.processParent[getBarId(this._rowIndex)][0]);
					}
				});
				gantt.data = gantt.data.concat(data);
			}
		});
	};

	DWZ.ajax({
		url: hostUrl + '/operationArrangement/getControlProcessOperations',
		data: {
			orderNums: orderNums,
			controlNums: controlNums,
			startDate: $startDate,
			endDate: $endDate
		},
		async: false,
		dataType: 'json',
		alert: false,
		success: function(json) {
			labelTemp = json.label || '{operationTaskNum}';
			prepareArrangementData(json);
			data = uniteOperationTasks(json.controls, json.operationTaskMap);
			if (data && data.length) {
				$jgantt.jGantt('fillData', data);
			}
			// 更新所有的父进度条
			$.each(data, function(){
				// 筛选有确认点工序的管理号
				if (this.processOperations.length > 0) {
					gantt.updatePaternalBar(gantt.processParent[getBarId(this._rowIndex)][0]);
				}
			});
			// 记录作业单元
			$('select[name=workUnitCode]', gantt.$left_content).each(function() {
				// 记录初始值
				$(this).attr('originalValue', this.value);
			});
			if (json.otherOrderNums && json.otherOrderNums.length && json.otherControlNums && json.otherControlNums.length) {
				getHistoryData(json.otherOrderNums, json.otherControlNums);
				console.log(json.otherOrderNums, json.otherControlNums);
			}
		}
	});
	
	gantt.$left_content.on('change', 'input.date', dateTimeChange);
	gantt.$left_content.on('focus', 'input.date', function() {
		$(this).removeClass('setValueModel');
	});

	// 作业单元改变时更新数据
	gantt.$left_content.on('change', 'select[name=workUnitCode]', function() {
		var $this = $(this), $row = $this.closest('.dataRow'), rowIndex = $row.attr('rowIndex'), workUnitCode = this.value, originalValue = $this.attr('originalValue');
		if (workUnitCode) {
			// 有初始值
			if (originalValue) {
				var barId = getBarId(rowIndex);
				removeWorkUnitProcess(originalValue, barId);
				if ($jgantt.jGantt('getBar', barId).length) {
					$jgantt.jGantt('removeProcessBar', barId);
				}
			}
			$this.attr('originalValue', workUnitCode);
			$.extend(gantt.getProcessData(rowIndex), {
				workUnitCode: workUnitCode,
				workUnitText: $this.find('option:selected').text()
			});
		}
	});

	graphPanel.on('dblclick', '.jgantt-bar', function() {
		var $bar = $(this);
		if ($bar.is('.rootBar')) {
			return false;
		}
		var processData = gantt.getProcessData(this.id);
		if ((processData.statusECode && processData.statusECode > 1) || processData.disabled) {
			return false;
		}
		separateTask(processData);
		return false;
	});

	/**
	 * 保存
	 */
	$('#saveOperationTasks', $page).click(function() {
		var parentObjs = {}, operationTasks = [], barIdCache = {}, doIssue = function() {
			$('>.jgantt-bar:not([disabled])', gantt.$right_content).each(function() {
				var barId = this.id, rowId = barId2RowId(this.id), $row = gantt.getRow(rowId), data = $jgantt.jGantt('getProcessData', rowId), obj = {
					operationTaskNum: data.operationTaskNum || '',
					productionControlNum: data._parent.productionControlNum,
					productionOrderNum: data._parent.productionOrderNum,
					processOperationId: data.id,
					operationCode: data.operationCode,
					plannedQuantity: data.plannedQuantity || data._parent.plannedQuantity,
					plannedHours: secondsToHours(data.produceTime) || 0.01,
					plannedStartDateTime: data.start,
					plannedendDateTime: data.end,
					plannedWorkUnitCode: $('select[name=workUnitCode]', $row).val(),
					statusECode: data.statusECode || '1'
				}
				barIdCache[obj.productionControlNum + '_' + obj.processOperationId] = this.id;
				operationTasks.push(obj);
			});
			if (operationTasks.length) {
				DWZ.ajax({
					type: 'POST',
					url: hostUrl + '/operationArrangement/saveOperationTasks',
					data: {
						operationTasks: JSON.stringify(operationTasks)
					},
					async: false,
					dataType: 'json',
					success: function(json) {
						ajaxCallBack();
					}
				});
			} else {
				alertMsg.error('没有可保存的工序任务计划！');
			}
		};
		doIssue();
	});

	var operateOperationTasks = function(sourceStatus) {
		var rowIndexs = getSelectedRowIndexs();
		if (rowIndexs.length) {
			var operationTaskNums = [], rowDataCache = {}, unarrangedControls = [];
			$.each(data, function() {
				if (rowIndexs.length && rowIndexs.indexOf(this._rowIndex) == -1) {
					return true;
				}
				var contol = this;
				// 下达操作要求所有工序均排产
				if (sourceStatus === 1) {
					var unarranged = false;
					$.each(this.processOperations, function() {
						if (!this.operationTaskNum) {
							unarranged = true;
							return true;
						}
					});
					if (unarranged) {
						unarrangedControls.push(this.productionControlNum);
						return true;
					}
				}
				$.each(this.processOperations, function() {
					if (this.operationTaskNum && this.statusECode && parseInt(this.statusECode) == sourceStatus) {
						operationTaskNums.push(contol.productionControlNum + ';' +this.operationTaskNum);
						rowDataCache[contol.productionControlNum + ';' +this.operationTaskNum] = getRowId(this._rowIndex);
					}
				});
			});
			if (operationTaskNums.length) {
				var doOperate = function() {
					DWZ.ajax({
						url: hostUrl + '/operationArrangement/' + (sourceStatus === 1 ? 'issueOperationTasks' : 'releaseOperationTasks'),
						data: {
							operationTaskNums: operationTaskNums.join(',')
						},
						alert: false,
						success: function(json) {
							if (!json.data) {
								alertMsg.correct(json.message);
							} else {
								DWZ.showDetailedReports({
									data: json
								});
							}
							ajaxCallBack();
						}
					});
				};
				if (unarrangedControls.length) {
					alertMsg.confirm('仅下达所有工序均排产完的管理号，是否继续？', {okCall: doOperate});
				} else {
					doOperate();
				}
			} else {
				if (unarrangedControls.length) {
					alertMsg.error('管理号下的所有工序均安排之后才能下达！');
				} else {
					alertMsg.error('没有选中有效的工序任务单！');
				}
			}
		} else {
			alertMsg.error('没有选中的生产管理号！');
		}
	};

	/**
	 * 下达
	 */
	$('#issueOperationTasks', $page).click(function() {
		operateOperationTasks(1);
	});

	/**
	 * 撤销下达
	 */
	$('#releaseOperationTasks', $page).click(function() {
		operateOperationTasks(2);
	});

	/**
	 * 获取最后的结束时间
	 */
	var getLatestEnd = function(obj1, obj2) {
		if (buildDateTime(obj1.startDate, obj1.startTimeObj) > buildDateTime(obj2.startDate, obj2.startTimeObj)) {
			return obj1;
		} else {
			return obj2;
		}
	},
	/**
	 * 重排单一管理号
	 */
	arrangeControl = function(assignUnit, startIndex) {
		var controlQuantity = this.plannedQuantity, workCenterCode = this.workCenterCode, controlNum = this.productionControlNum, defaultStartDate = new Date();
		defaultStartDate.setDate(defaultStartDate.getDate() + 1);
		// 记录前一个工序的相关数据
		var preProcessEnd, processEnd, processIds = [0], processEnds = [{
			startDate: defaultStartDate.formatDate('yyyy-MM-dd')
		}], barId, preBarId, isSameProcess = false;

		$.each(this.processOperations, function() {
			var id = this.id;
			// 新的工序
			if (processIds[processIds.length - 1] !== id) {
				processIds.push(id);
				processEnds.push({});
				isSameProcess = false;
				if (processEnds.length > 2) {
					processEnds.shift();
				}
			} else {
				isSameProcess = true;
			}
			preProcessEnd = processEnds[0];

			// 如果任务单状态不为1或者拖拽时，比较记录当前最大结束时间
			if ((this.statusECode && parseInt(this.statusECode) > 1) || (startIndex !== undefined && this._rowIndex < startIndex)) {
				processEnd = getCalendarDay(getCalendarDays(this.workUnitCode, this.workCenterCode), this.end);
				processEnd.startTimeObj = processEnd;
				if (isSameProcess) {
					var end = processEnds[1];
					processEnds[1] = getLatestEnd(end, processEnd);
				} else {
					processEnds[1] = processEnd;
				}
				/*
				if (this._rowIndex == startIndex - 1) {
					console.log(processEnds[1]);
				}
				*/
				return true;
			}
			// 无可用作业单元时，退出循环
			if (!this.workUnitCodes) {
				$('.warning-icon', gantt.getRow(getRowId(this._rowIndex))).attr('title', '没有可用的作业单元，不能自动排产').show();
				return false;
			}
			// 工序任务单数量，自己分配数量了以自己数量为准，否则以管理号数量为准
			var task = this, quantity = task.plannedQuantity || controlQuantity, rowIndex = task._rowIndex, workUnitCodes = task.workUnitCodes.split(',');

			// 指定作业单元时，唯一作业单元可选
			var $row = gantt.getRow(getRowId(rowIndex));
			if (assignUnit) {
				workUnitCodes = [task.workUnitCode];
				$row.find('select[name=workUnitCode]').val(task.workUnitCode);
			}

			var optimumUnit = seekOptimumUnit(buildDateTime(preProcessEnd.startDate, preProcessEnd.startTimeObj), workCenterCode, workUnitCodes, quantity, id, rowIndex);

			if (!optimumUnit) {
				if (task.operationTaskNum && task.start && task.end && task.workUnitCode) {
					console.log(task.operationTaskNum, '无法自动排产，需要手动调整');
				}
				return false;
			}
			$('select[name=workUnitCode]', $row).val(optimumUnit.workUnitCode);
			
			processEnd = {
				startDate: optimumUnit.startDate,
				startTimeObj: optimumUnit.startTimeObj
			};

			if (isSameProcess) {
				var end = processEnds[1];
				processEnds[1] = getLatestEnd(end, processEnd);
			} else {
				processEnds[1] = processEnd;
			}

			$.extend(this, optimumUnit);
			// 仅更新
			if (startIndex) {
				$jgantt.jGantt('updateProcessBar', getBarId(this._rowIndex), this, false, false);
			} else {
				barId = $jgantt.jGantt('createProcessBar', this);
			}
		});
		if (barId && barId != preBarId) {
			$jgantt.jGantt('updatePaternalBar', barId);
			preBarId = barId;
		}
	},
	/**
	 * 重排
	 */
	arrangeAll = function() {
		var rowIndexs = arguments[0] || [];

		// 清除需要重排的进度条
		if (rowIndexs.length) {
			$.each(rowIndexs, function() {
				$.each(gantt.processParent[getBarId(this)] || [], function() {
					var statusECode = gantt.getProcessData(this).statusECode;
					if (statusECode && parseInt(statusECode) > 1) {
						return true;
					}
					$jgantt.jGantt('removeProcessBar', this);
				});
			});
		} else {
			// 重排全部时按照优先级排序
			prioritySort();
			$('.rootRow:not([readonly])', gantt.$left_content).each(function() {
				$.each(gantt.processParent[getBarId($(this).attr('rowIndex'))] || [], function() {
					var statusECode = gantt.getProcessData(this).statusECode;
					if (statusECode && parseInt(statusECode) > 1) {
						return true;
					}
					$jgantt.jGantt('removeProcessBar', this);
				});
			});
		}
		// 遍历重排
		$.each(priorityData || data, function() {
			if (rowIndexs.length && rowIndexs.indexOf(this._rowIndex) == -1) {
				return true;
			}
			arrangeControl.apply(this);
		});
	};

	/**
	 * 重排所有
	 */
	$('#arrangeAll', $page).click(arrangeAll);

	/**
	 * 重排所选
	 */
	$('#arrangeSelected', $page).click(function() {
		var rowIndexs = getSelectedRowIndexs();
		if (rowIndexs.length) {
			arrangeAll(rowIndexs);
		} else {
			alertMsg.error('没有选中的生产管理号！');
		}
	});
};